import { Context } from 'koa';
import { query, queryOne } from '../database/mysql';
import { Notification, NotificationRead, NotificationPush, User } from '../database/models';
import { utils } from '../utils/utils';
import { success, error } from '../utils/response';
import { ResponseCode } from '../config/responseCode';

/**
 * 创建通知（仅管理员）
 */
export async function createNotification(ctx: Context): Promise<void> {
  const { title, content, type = 'info' } = ctx.request.body as {
    title?: string;
    content?: string;
    type?: string;
  };

  if (!title || !content) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知标题和内容不能为空');
    return;
  }

  // 验证通知类型
  const validTypes = ['info', 'warn', 'error', 'success'];
  if (!validTypes.includes(type)) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知类型无效，必须是: info/warn/error/success');
    return;
  }

  const id = utils.generateUUID();
  await query(
    'INSERT INTO notifications (id, title, content, type, status) VALUES (?, ?, ?, ?, 1)',
    [id, title, content, type]
  );

  const newNotification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  success(ctx, newNotification);
}

/**
 * 更新通知（仅管理员）
 */
export async function updateNotification(ctx: Context): Promise<void> {
  const { id, title, content, type, status } = ctx.request.body as {
    id?: string;
    title?: string;
    content?: string;
    type?: string;
    status?: number;
  };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  // 检查通知是否存在
  const notification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  if (!notification) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在');
    return;
  }

  // 更新通知信息
  const updates: string[] = [];
  const params: any[] = [];

  if (title !== undefined) {
    updates.push('title = ?');
    params.push(title);
  }
  if (content !== undefined) {
    updates.push('content = ?');
    params.push(content);
  }
  if (type !== undefined) {
    // 验证通知类型
    const validTypes = ['info', 'warn', 'error', 'success'];
    if (!validTypes.includes(type)) {
      error(ctx, ResponseCode.BAD_REQUEST, '通知类型无效，必须是: info/warn/error/success');
      return;
    }
    updates.push('type = ?');
    params.push(type);
  }
  if (status !== undefined) {
    updates.push('status = ?');
    params.push(status);
  }

  if (updates.length > 0) {
    params.push(id);
    await query(`UPDATE notifications SET ${updates.join(', ')} WHERE id = ?`, params);
  }

  const updatedNotification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  success(ctx, updatedNotification);
}

/**
 * 删除通知（仅管理员）
 */
export async function deleteNotification(ctx: Context): Promise<void> {
  const { id } = ctx.request.body as { id?: string };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  // 检查通知是否存在
  const notification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  if (!notification) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在');
    return;
  }

  // 删除已读关系
  await query('DELETE FROM notification_reads WHERE notification_id = ?', [id]);
  
  // 删除推送记录
  await query('DELETE FROM notification_pushes WHERE notification_id = ?', [id]);

  // 删除通知
  await query('DELETE FROM notifications WHERE id = ?', [id]);

  success(ctx, { message: '删除成功' });
}

/**
 * 查询通知列表（后台管理 - 仅管理员）
 */
export async function getNotificationList(ctx: Context): Promise<void> {
  const { page = 1, pageSize = 10, type, status } = ctx.request.body as {
    page?: number;
    pageSize?: number;
    type?: string;
    status?: number;
  };

  // 限制每页最大数量
  const maxPageSize = 100;
  const limitPageSize = Math.min(pageSize, maxPageSize);

  let sql = 'SELECT n.* FROM notifications n WHERE 1=1';
  const params: any[] = [];

  if (type) {
    sql += ' AND n.type = ?';
    params.push(type);
  }
  if (status !== undefined) {
    sql += ' AND n.status = ?';
    params.push(status);
  }

  sql += ' ORDER BY n.created_at DESC LIMIT ? OFFSET ?';
  const offset = (page - 1) * limitPageSize;
  params.push(limitPageSize, offset);

  const notifications = await query<Notification>(sql, params);

  // 获取每个通知的推送用户数
  if (notifications.length > 0) {
    const notificationIds = notifications.map(n => n.id);
    const placeholders = notificationIds.map(() => '?').join(',');
    const pushCounts = await query<{ notification_id: string; count: number }>(
      `SELECT notification_id, COUNT(*) as count 
       FROM notification_pushes 
       WHERE notification_id IN (${placeholders}) 
       GROUP BY notification_id`,
      notificationIds
    );

    const pushCountMap = new Map(pushCounts.map(p => [p.notification_id, Number(p.count) || 0]));

    const notificationList = notifications.map(notification => ({
      ...notification,
      push_count: pushCountMap.get(notification.id) || 0, // 推送用户数
    }));

    // 计算总数
    let countSql = 'SELECT COUNT(*) as count FROM notifications n WHERE 1=1';
    const countParams: any[] = [];

    if (type) {
      countSql += ' AND n.type = ?';
      countParams.push(type);
    }
    if (status !== undefined) {
      countSql += ' AND n.status = ?';
      countParams.push(status);
    }

    const totalResult = await queryOne<{ count: number }>(countSql, countParams);

    success(ctx, {
      list: notificationList,
      total: totalResult?.count || 0,
      page,
      pageSize: limitPageSize,
    });
  } else {
    success(ctx, {
      list: [],
      total: 0,
      page,
      pageSize: limitPageSize,
    });
  }
}

/**
 * 查询通知详情（后台管理 - 仅管理员）
 */
export async function getNotificationDetail(ctx: Context): Promise<void> {
  const { id } = ctx.request.body as { id?: string };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  const notification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  if (!notification) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在');
    return;
  }

  // 获取推送用户数
  const pushCountResult = await queryOne<{ count: number }>(
    'SELECT COUNT(*) as count FROM notification_pushes WHERE notification_id = ?',
    [id]
  );

  success(ctx, {
    ...notification,
    push_count: pushCountResult?.count || 0,
  });
}

/**
 * 推送通知（仅管理员）
 * 可以推送给所有用户或指定用户列表
 */
export async function pushNotification(ctx: Context): Promise<void> {
  const { id, user_ids } = ctx.request.body as {
    id?: string;
    user_ids?: string[]; // 如果为空或未提供，则推送给所有用户
  };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  // 检查通知是否存在
  const notification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ?', [id]);
  if (!notification) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在');
    return;
  }

  // 检查通知是否启用
  if (notification.status !== 1) {
    error(ctx, ResponseCode.BAD_REQUEST, '只能推送已启用的通知');
    return;
  }

  let targetUserIds: string[] = [];

  if (user_ids && user_ids.length > 0) {
    // 推送给指定用户
    targetUserIds = user_ids;
  } else {
    // 推送给所有启用状态的用户
    const allUsers = await query<{ id: string }>('SELECT id FROM users WHERE status = 1');
    targetUserIds = allUsers.map(u => u.id);
  }

  if (targetUserIds.length === 0) {
    error(ctx, ResponseCode.BAD_REQUEST, '没有可推送的用户');
    return;
  }

  // 批量创建推送记录（跳过已存在的推送记录）
  let pushCount = 0;
  for (const userId of targetUserIds) {
    // 检查是否已推送
    const existingPush = await queryOne<NotificationPush>(
      'SELECT * FROM notification_pushes WHERE notification_id = ? AND user_id = ?',
      [id, userId]
    );

    if (!existingPush) {
      const pushId = utils.generateUUID();
      await query(
        'INSERT INTO notification_pushes (id, notification_id, user_id) VALUES (?, ?, ?)',
        [pushId, id, userId]
      );
      pushCount++;
    }
  }

  success(ctx, {
    message: `推送成功，共推送给 ${pushCount} 个用户`,
    total_users: targetUserIds.length,
    new_pushes: pushCount,
    already_pushed: targetUserIds.length - pushCount,
  });
}

/**
 * 查询我的通知列表（前台用户）
 * 只返回推送给当前用户的通知
 */
export async function getMyNotifications(ctx: Context): Promise<void> {
  const { page = 1, pageSize = 10, type, unread } = ctx.request.body as {
    page?: number;
    pageSize?: number;
    type?: string;
    unread?: boolean; // 是否只查询未读通知
  };

  const currentUser = ctx.state.user as User;
  const userId = currentUser.id;

  // 限制每页最大数量
  const maxPageSize = 100;
  const limitPageSize = Math.min(pageSize, maxPageSize);

  // 查询推送给当前用户的通知
  let sql = `SELECT n.*, np.created_at as pushed_at 
             FROM notifications n
             INNER JOIN notification_pushes np ON n.id = np.notification_id
             WHERE np.user_id = ? AND n.status = 1`;
  const params: any[] = [userId];

  if (type) {
    sql += ' AND n.type = ?';
    params.push(type);
  }

  // 如果只查询未读通知，需要关联已读关系表
  if (unread) {
    sql += ` AND NOT EXISTS (
               SELECT 1 FROM notification_reads nr 
               WHERE nr.notification_id = n.id AND nr.user_id = ?
             )`;
    params.push(userId);
  }

  sql += ' ORDER BY np.created_at DESC LIMIT ? OFFSET ?';
  const offset = (page - 1) * limitPageSize;
  params.push(limitPageSize, offset);

  const notifications = await query<Notification & { pushed_at: Date }>(sql, params);

  // 获取当前用户的已读状态
  if (notifications.length > 0) {
    const notificationIds = notifications.map(n => n.id);
    const placeholders = notificationIds.map(() => '?').join(',');
    const readRecords = await query<NotificationRead>(
      `SELECT * FROM notification_reads WHERE notification_id IN (${placeholders}) AND user_id = ?`,
      [...notificationIds, userId]
    );

    const readMap = new Map(readRecords.map(r => [r.notification_id, true]));

    const notificationList = notifications.map(notification => ({
      id: notification.id,
      title: notification.title,
      content: notification.content,
      type: notification.type,
      is_read: readMap.has(notification.id) || false,
      pushed_at: notification.pushed_at,
      created_at: notification.created_at,
      updated_at: notification.updated_at,
    }));

    // 计算总数
    let countSql = `SELECT COUNT(*) as count 
                    FROM notifications n
                    INNER JOIN notification_pushes np ON n.id = np.notification_id
                    WHERE np.user_id = ? AND n.status = 1`;
    const countParams: any[] = [userId];

    if (type) {
      countSql += ' AND n.type = ?';
      countParams.push(type);
    }

    if (unread) {
      countSql += ` AND NOT EXISTS (
                      SELECT 1 FROM notification_reads nr 
                      WHERE nr.notification_id = n.id AND nr.user_id = ?
                    )`;
      countParams.push(userId);
    }

    const totalResult = await queryOne<{ count: number }>(countSql, countParams);

    success(ctx, {
      list: notificationList,
      total: totalResult?.count || 0,
      page,
      pageSize: limitPageSize,
    });
  } else {
    success(ctx, {
      list: [],
      total: 0,
      page,
      pageSize: limitPageSize,
    });
  }
}

/**
 * 查询我的通知详情（前台用户）
 */
export async function getMyNotificationDetail(ctx: Context): Promise<void> {
  const { id } = ctx.request.body as { id?: string };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  const currentUser = ctx.state.user as User;
  const userId = currentUser.id;

  // 检查通知是否推送给当前用户
  const pushRecord = await queryOne<NotificationPush>(
    'SELECT * FROM notification_pushes WHERE notification_id = ? AND user_id = ?',
    [id, userId]
  );

  if (!pushRecord) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在或未推送给您');
    return;
  }

  const notification = await queryOne<Notification>('SELECT * FROM notifications WHERE id = ? AND status = 1', [id]);
  if (!notification) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在或已禁用');
    return;
  }

  // 检查是否已读
  const readRecord = await queryOne<NotificationRead>(
    'SELECT * FROM notification_reads WHERE notification_id = ? AND user_id = ?',
    [id, userId]
  );

  success(ctx, {
    ...notification,
    is_read: !!readRecord,
    pushed_at: pushRecord.created_at,
  });
}

/**
 * 标记通知为已读（前台用户）
 */
export async function markNotificationAsRead(ctx: Context): Promise<void> {
  const { id } = ctx.request.body as { id?: string };

  if (!id) {
    error(ctx, ResponseCode.BAD_REQUEST, '通知ID不能为空');
    return;
  }

  const currentUser = ctx.state.user as User;
  const userId = currentUser.id;

  // 检查通知是否推送给当前用户
  const pushRecord = await queryOne<NotificationPush>(
    'SELECT * FROM notification_pushes WHERE notification_id = ? AND user_id = ?',
    [id, userId]
  );

  if (!pushRecord) {
    error(ctx, ResponseCode.NOT_FOUND, '通知不存在或未推送给您');
    return;
  }

  // 检查是否已读
  const existingRead = await queryOne<NotificationRead>(
    'SELECT * FROM notification_reads WHERE notification_id = ? AND user_id = ?',
    [id, userId]
  );

  if (!existingRead) {
    // 创建已读记录
    const readId = utils.generateUUID();
    await query(
      'INSERT INTO notification_reads (id, notification_id, user_id) VALUES (?, ?, ?)',
      [readId, id, userId]
    );
  }

  success(ctx, { message: '标记已读成功' });
}

/**
 * 标记所有通知为已读（前台用户）
 */
export async function markAllNotificationsAsRead(ctx: Context): Promise<void> {
  const currentUser = ctx.state.user as User;
  const userId = currentUser.id;

  // 获取所有推送给当前用户但未读的通知
  const unreadNotifications = await query<Notification>(
    `SELECT n.* FROM notifications n
     INNER JOIN notification_pushes np ON n.id = np.notification_id
     LEFT JOIN notification_reads nr ON n.id = nr.notification_id AND nr.user_id = ?
     WHERE np.user_id = ? AND n.status = 1 AND nr.id IS NULL`,
    [userId, userId]
  );

  // 批量创建已读记录
  for (const notification of unreadNotifications) {
    const readId = utils.generateUUID();
    await query(
      'INSERT INTO notification_reads (id, notification_id, user_id) VALUES (?, ?, ?)',
      [readId, notification.id, userId]
    );
  }

  success(ctx, { message: `已标记 ${unreadNotifications.length} 条通知为已读` });
}
